package algorithm7.leetcode.剑指Offer;

import algorithm7.niucode.util.ListNode;

/**
 * 剑指 Offer 24. 反转链表
 * 206. 反转链表
 *          LC206
 *          JZ24
 */
public class JZ24 {

/*

剑指 Offer 24. 反转链表

定义一个函数，输入一个链表的头节点，反转该链表并输出反转后链表的头节点。

示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

*/

    public ListNode reverseList(ListNode head) {
//        return handle1(head);
//        return handle2(head, null);
//        return handle3(head);
        return handle4(head);
    }

    /**
     * 头插法，新建一个链表
     */
    private ListNode handle4(ListNode head) {
        ListNode cur = head;
        ListNode newHead = null;
        while (cur != null) {
            ListNode node = new ListNode(cur.val);
            node.next = newHead;
            newHead = node;
            cur = cur.next;
        }
        return newHead;
    }

    /**
     * 递归
     *
     * @return head
     */
    private ListNode handle3(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;//将head.next节点的指针反转，由head -> head.next 改为head.next -> head
        head.next = null;
        return newHead;
    }

    /**
     * 递归
     *
     * @param cur 当前节点
     * @param pre 前一个节点
     * @return head
     */
    private ListNode handle2(ListNode cur, ListNode pre) {
        if (cur == null) {
            return pre;
        }
        ListNode next = cur.next;
        cur.next = pre;
        ListNode head = handle2(next, cur);
        return head;
    }

    /**
     * 迭代
     * @param head 原链表头
     * @return head
     */
    private ListNode handle1(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }


    public static void main(String[] args) {

    }


}
